package com.bigkoo.pickerview.utils;

import android.annotation.SuppressLint;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

import androidx.annotation.Nullable;

public class ChinaDate {
    /**
     * 支持转换的最小农历年份
     */
    public static final int MIN_YEAR = 1900;
    
    /**
     * 支持转换的最大农历年份
     */
    public static final int MAX_YEAR = 2099;
    
    /**
     * 用来表示1900年到2099年间农历年份的相关信息，共24位bit的16进制表示，其中：
     * 1. 前4位表示该年闰哪个月；
     * 2. 5-17位表示农历年份13个月的大小月分布，0表示小，1表示大；
     * 3. 最后7位表示农历年首（正月初一）对应的公历日期,前两位十进制表示月份，后5位十进制表示日期。
     * <p>
     * 以2014年的数据0x955ABF为例说明：
     * 1001 0101 0101 1010 1011 1111
     *
     * 1001          0101 0101 1010 1                 01                                  11111
     * 闰九月     中间13位数表示农历每月大小    表示农历正月对应的公历月份               表示农历正月日期对应的公历日期
     * 此处表示2014农历春节1月，阳历也是1月     此处表示农历正月初一对应阳历31号
     */
    private static final int[] LUNAR_INFO = {
        0x84B6BF,/*1900*/
        0x04AE53, 0x0A5748, 0x5526BD, 0x0D2650, 0x0D9544, 0x46AAB9, 0x056A4D, 0x09AD42, 0x24AEB6, 0x04AE4A,/*1901-1910*/
        0x6A4DBE, 0x0A4D52, 0x0D2546, 0x5D52BA, 0x0B544E, 0x0D6A43, 0x296D37, 0x095B4B, 0x749BC1, 0x049754,/*1911-1920*/
        0x0A4B48, 0x5B25BC, 0x06A550, 0x06D445, 0x4ADAB8, 0x02B64D, 0x095742, 0x2497B7, 0x04974A, 0x664B3E,/*1921-1930*/
        0x0D4A51, 0x0EA546, 0x56D4BA, 0x05AD4E, 0x02B644, 0x393738, 0x092E4B, 0x7C96BF, 0x0C9553, 0x0D4A48,/*1931-1940*/
        0x6DA53B, 0x0B554F, 0x056A45, 0x4AADB9, 0x025D4D, 0x092D42, 0x2C95B6, 0x0A954A, 0x7B4ABD, 0x06CA51,/*1941-1950*/
        0x0B5546, 0x555ABB, 0x04DA4E, 0x0A5B43, 0x352BB8, 0x052B4C, 0x8A953F, 0x0E9552, 0x06AA48, 0x6AD53C,/*1951-1960*/
        0x0AB54F, 0x04B645, 0x4A5739, 0x0A574D, 0x052642, 0x3E9335, 0x0D9549, 0x75AABE, 0x056A51, 0x096D46,/*1961-1970*/
        0x54AEBB, 0x04AD4F, 0x0A4D43, 0x4D26B7, 0x0D254B, 0x8D52BF, 0x0B5452, 0x0B6A47, 0x696D3C, 0x095B50,/*1971-1980*/
        0x049B45, 0x4A4BB9, 0x0A4B4D, 0xAB25C2, 0x06A554, 0x06D449, 0x6ADA3D, 0x0AB651, 0x095746, 0x5497BB,/*1981-1990*/
        0x04974F, 0x064B44, 0x36A537, 0x0EA54A, 0x86B2BF, 0x05AC53, 0x0AB647, 0x5936BC, 0x092E50, 0x0C9645,/*1991-2000*/
        0x4D4AB8, 0x0D4A4C, 0x0DA541, 0x25AAB6, 0x056A49, 0x7AADBD, 0x025D52, 0x092D47, 0x5C95BA, 0x0A954E,/*2001-2010*/
        0x0B4A43, 0x4B5537, 0x0AD54A, 0x955ABF, 0x04BA53, 0x0A5B48, 0x652BBC, 0x052B50, 0x0A9345, 0x474AB9,/*2011-2020*/
        0x06AA4C, 0x0AD541, 0x24DAB6, 0x04B64A, 0x6a573D, 0x0A4E51, 0x0D2646, 0x5E933A, 0x0D534D, 0x05AA43,/*2021-2030*/
        0x36B537, 0x096D4B, 0xB4AEBF, 0x04AD53, 0x0A4D48, 0x6D25BC, 0x0D254F, 0x0D5244, 0x5DAA38, 0x0B5A4C,/*2031-2040*/
        0x056D41, 0x24ADB6, 0x049B4A, 0x7A4BBE, 0x0A4B51, 0x0AA546, 0x5B52BA, 0x06D24E, 0x0ADA42, 0x355B37,/*2041-2050*/
        0x09374B, 0x8497C1, 0x049753, 0x064B48, 0x66A53C, 0x0EA54F, 0x06AA44, 0x4AB638, 0x0AAE4C, 0x092E42,/*2051-2060*/
        0x3C9735, 0x0C9649, 0x7D4ABD, 0x0D4A51, 0x0DA545, 0x55AABA, 0x056A4E, 0x0A6D43, 0x452EB7, 0x052D4B,/*2061-2070*/
        0x8A95BF, 0x0A9553, 0x0B4A47, 0x6B553B, 0x0AD54F, 0x055A45, 0x4A5D38, 0x0A5B4C, 0x052B42, 0x3A93B6,/*2071-2080*/
        0x069349, 0x7729BD, 0x06AA51, 0x0AD546, 0x54DABA, 0x04B64E, 0x0A5743, 0x452738, 0x0D264A, 0x8E933E,/*2081-2090*/
        0x0D5252, 0x0DAA47, 0x66B53B, 0x056D4F, 0x04AE45, 0x4A4EB9, 0x0A4D4C, 0x0D1541, 0x2D92B5          /*2091-2099*/
    };
    
    private static final int[] SOLAR_1_1 = {1887, 0xec04c, 0xec23f, 0xec435, 0xec649,
        0xec83e, 0xeca51, 0xecc46, 0xece3a, 0xed04d, 0xed242, 0xed436,
        0xed64a, 0xed83f, 0xeda53, 0xedc48, 0xede3d, 0xee050, 0xee244,
        0xee439, 0xee64d, 0xee842, 0xeea36, 0xeec4a, 0xeee3e, 0xef052,
        0xef246, 0xef43a, 0xef64e, 0xef843, 0xefa37, 0xefc4b, 0xefe41,
        0xf0054, 0xf0248, 0xf043c, 0xf0650, 0xf0845, 0xf0a38, 0xf0c4d,
        0xf0e42, 0xf1037, 0xf124a, 0xf143e, 0xf1651, 0xf1846, 0xf1a3a,
        0xf1c4e, 0xf1e44, 0xf2038, 0xf224b, 0xf243f, 0xf2653, 0xf2848,
        0xf2a3b, 0xf2c4f, 0xf2e45, 0xf3039, 0xf324d, 0xf3442, 0xf3636,
        0xf384a, 0xf3a3d, 0xf3c51, 0xf3e46, 0xf403b, 0xf424e, 0xf4443,
        0xf4638, 0xf484c, 0xf4a3f, 0xf4c52, 0xf4e48, 0xf503c, 0xf524f,
        0xf5445, 0xf5639, 0xf584d, 0xf5a42, 0xf5c35, 0xf5e49, 0xf603e,
        0xf6251, 0xf6446, 0xf663b, 0xf684f, 0xf6a43, 0xf6c37, 0xf6e4b,
        0xf703f, 0xf7252, 0xf7447, 0xf763c, 0xf7850, 0xf7a45, 0xf7c39,
        0xf7e4d, 0xf8042, 0xf8254, 0xf8449, 0xf863d, 0xf8851, 0xf8a46,
        0xf8c3b, 0xf8e4f, 0xf9044, 0xf9237, 0xf944a, 0xf963f, 0xf9853,
        0xf9a47, 0xf9c3c, 0xf9e50, 0xfa045, 0xfa238, 0xfa44c, 0xfa641,
        0xfa836, 0xfaa49, 0xfac3d, 0xfae52, 0xfb047, 0xfb23a, 0xfb44e,
        0xfb643, 0xfb837, 0xfba4a, 0xfbc3f, 0xfbe53, 0xfc048, 0xfc23c,
        0xfc450, 0xfc645, 0xfc839, 0xfca4c, 0xfcc41, 0xfce36, 0xfd04a,
        0xfd23d, 0xfd451, 0xfd646, 0xfd83a, 0xfda4d, 0xfdc43, 0xfde37,
        0xfe04b, 0xfe23f, 0xfe453, 0xfe648, 0xfe83c, 0xfea4f, 0xfec44,
        0xfee38, 0xff04c, 0xff241, 0xff436, 0xff64a, 0xff83e, 0xffa51,
        0xffc46, 0xffe3a, 0x10004e, 0x100242, 0x100437, 0x10064b, 0x100841,
        0x100a53, 0x100c48, 0x100e3c, 0x10104f, 0x101244, 0x101438,
        0x10164c, 0x101842, 0x101a35, 0x101c49, 0x101e3d, 0x102051,
        0x102245, 0x10243a, 0x10264e, 0x102843, 0x102a37, 0x102c4b,
        0x102e3f, 0x103053, 0x103247, 0x10343b, 0x10364f, 0x103845,
        0x103a38, 0x103c4c, 0x103e42, 0x104036, 0x104249, 0x10443d,
        0x104651, 0x104846, 0x104a3a, 0x104c4e, 0x104e43, 0x105038,
        0x10524a, 0x10543e, 0x105652, 0x105847, 0x105a3b, 0x105c4f,
        0x105e45, 0x106039, 0x10624c, 0x106441, 0x106635, 0x106849,
        0x106a3d, 0x106c51, 0x106e47, 0x10703c, 0x10724f, 0x107444,
        0x107638, 0x10784c, 0x107a3f, 0x107c53, 0x107e48};
    
    private static final int[] LUNAR_MONTH_DAYS = {1887, 0x1694, 0x16aa, 0x4ad5,
        0xab6, 0xc4b7, 0x4ae, 0xa56, 0xb52a, 0x1d2a, 0xd54, 0x75aa, 0x156a,
        0x1096d, 0x95c, 0x14ae, 0xaa4d, 0x1a4c, 0x1b2a, 0x8d55, 0xad4,
        0x135a, 0x495d, 0x95c, 0xd49b, 0x149a, 0x1a4a, 0xbaa5, 0x16a8,
        0x1ad4, 0x52da, 0x12b6, 0xe937, 0x92e, 0x1496, 0xb64b, 0xd4a,
        0xda8, 0x95b5, 0x56c, 0x12ae, 0x492f, 0x92e, 0xcc96, 0x1a94,
        0x1d4a, 0xada9, 0xb5a, 0x56c, 0x726e, 0x125c, 0xf92d, 0x192a,
        0x1a94, 0xdb4a, 0x16aa, 0xad4, 0x955b, 0x4ba, 0x125a, 0x592b,
        0x152a, 0xf695, 0xd94, 0x16aa, 0xaab5, 0x9b4, 0x14b6, 0x6a57,
        0xa56, 0x1152a, 0x1d2a, 0xd54, 0xd5aa, 0x156a, 0x96c, 0x94ae,
        0x14ae, 0xa4c, 0x7d26, 0x1b2a, 0xeb55, 0xad4, 0x12da, 0xa95d,
        0x95a, 0x149a, 0x9a4d, 0x1a4a, 0x11aa5, 0x16a8, 0x16d4, 0xd2da,
        0x12b6, 0x936, 0x9497, 0x1496, 0x1564b, 0xd4a, 0xda8, 0xd5b4,
        0x156c, 0x12ae, 0xa92f, 0x92e, 0xc96, 0x6d4a, 0x1d4a, 0x10d65,
        0xb58, 0x156c, 0xb26d, 0x125c, 0x192c, 0x9a95, 0x1a94, 0x1b4a,
        0x4b55, 0xad4, 0xf55b, 0x4ba, 0x125a, 0xb92b, 0x152a, 0x1694,
        0x96aa, 0x15aa, 0x12ab5, 0x974, 0x14b6, 0xca57, 0xa56, 0x1526,
        0x8e95, 0xd54, 0x15aa, 0x49b5, 0x96c, 0xd4ae, 0x149c, 0x1a4c,
        0xbd26, 0x1aa6, 0xb54, 0x6d6a, 0x12da, 0x1695d, 0x95a, 0x149a,
        0xda4b, 0x1a4a, 0x1aa4, 0xbb54, 0x16b4, 0xada, 0x495b, 0x936,
        0xf497, 0x1496, 0x154a, 0xb6a5, 0xda4, 0x15b4, 0x6ab6, 0x126e,
        0x1092f, 0x92e, 0xc96, 0xcd4a, 0x1d4a, 0xd64, 0x956c, 0x155c,
        0x125c, 0x792e, 0x192c, 0xfa95, 0x1a94, 0x1b4a, 0xab55, 0xad4,
        0x14da, 0x8a5d, 0xa5a, 0x1152b, 0x152a, 0x1694, 0xd6aa, 0x15aa,
        0xab4, 0x94ba, 0x14b6, 0xa56, 0x7527, 0xd26, 0xee53, 0xd54, 0x15aa,
        0xa9b5, 0x96c, 0x14ae, 0x8a4e, 0x1a4c, 0x11d26, 0x1aa4, 0x1b54,
        0xcd6a, 0xada, 0x95c, 0x949d, 0x149a, 0x1a2a, 0x5b25, 0x1aa4,
        0xfb52, 0x16b4, 0xaba, 0xa95b, 0x936, 0x1496, 0x9a4b, 0x154a,
        0x136a5, 0xda4, 0x15ac};
    
    public final static String[] nStr1 = new String[]{"", "正", "二", "三", "四",
        "五", "六", "七", "八", "九", "十", "冬", "腊"};
    private final static String[] Gan = new String[]{"甲", "乙", "丙", "丁", "戊",
        "己", "庚", "辛", "壬", "癸"};
    private final static String[] Zhi = new String[]{"子", "丑", "寅", "卯", "辰",
        "巳", "午", "未", "申", "酉", "戌", "亥"};
    private final static String[] Animals = new String[]{"鼠", "牛", "虎", "兔",
        "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};
    
    
    private final static String[] solarTerm = new String[]{"小寒", "大寒", "立春",
        "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑",
        "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"};
    
    private final static String[] sFtv = new String[]{"0101*元旦", "0214 情人节",
        "0308 妇女节", "0312 植树节", "0315 消费者权益日", "0401 愚人节", "0501 劳动节",
        "0504 青年节", "0512 护士节", "0601 儿童节", "0701 建党节", "0801 建军节",
        "0808 父亲节", "0909 mzd逝世纪念", "0910 教师节", "0928 孔子诞辰", "1001*国庆节",
        "1006 老人节", "1024 联合国日", "1112 孙中山诞辰", "1220 澳门回归", "1225 圣诞节",
        "1226 mzd诞辰"};
    
    private final static String[] lFtv = new String[]{"0101*农历春节",
        "0115 元宵节", "0505 端午节", "0707 七夕情人节", "0815 中秋节", "0909 重阳节",
        "1208 腊八节", "1224 小年", "0100*除夕"};
    
    private final static int[] dayArr = new int[]{20, 19, 21, 20, 21, 22, 23, 23, 23, 24, 23, 22};
    private final static String[] constellationArr = new String[]{"摩羯座", "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "摩羯座"};
    
    /**
     * 获取一年中的天数
     *
     * @param y 年份
     * @return 总天数
     */
    private static int getYearTotalDays(int y) {
        int i, sum = 348;
        if (getLeapMonth(y) != 0) {
            sum = 377;
        }
        int monthInfo = LUNAR_INFO[y - MIN_YEAR] & 0x0FFF80;
        for (i = 0x80000; i > 0x7; i >>= 1) {
            if ((monthInfo & i) != 0)
                sum += 1;
        }
        return sum;
    }
    
    /**
     * 判断某一年闰月总天数
     *
     * @param y 年份
     * @return 闰月的总天数
     */
    public static int getLeapMonthDays(int y) {
        return getMonthDays(y, getLeapMonth(y));
    }
    
    /**
     * 获取某一年闰哪个月
     *
     * @param y 年份
     * @return 闰的月份(1 - 12)，如果没有闰月则返回0
     */
    public static int getLeapMonth(int y) {
        return (LUNAR_INFO[y - MIN_YEAR] & 0xF00000) >> 20;
    }
    
    /**
     * 获取指定年月的总天数
     *
     * @param y 将要计算的年份
     * @param m 将要计算的月份，1-12
     * @return 指定年月的总天数
     */
    public static int getMonthDays(int y, int m) {
        if ((LUNAR_INFO[y - MIN_YEAR] & (0x100000 >> m)) == 0)
            return 29;
        else
            return 30;
    }
    
    /**
     * 获取生肖
     */
    public static String getYearAnimal(int y) {
        return Animals[(y - 4) % 12];
    }
    
    /**
     * 获取干支
     *
     * @param num 月日的offset 传回干支,0是甲子
     * @return 干支
     */
    private static String cyclicalm(int num) {
        return (Gan[num % 10] + Zhi[num % 12]);
    }
    
    /**
     * 获取年份对应的干支
     *
     * @param y 0是甲子
     * @return 干支
     */
    public static String cyclical(int y) {
        int num = y - 1900 + 36;
        return (cyclicalm(num));
    }
    
    /**
     * 天转化为农历表示
     */
    public static String getChinaDay(int day) {
        String a = "";
        if (day == 10)
            return "初十";
        if (day == 20)
            return "二十";
        if (day == 30)
            return "三十";
        int two = (int) ((day) / 10);
        if (two == 0)
            a = "初";
        if (two == 1)
            a = "十";
        if (two == 2)
            a = "廿";
        if (two == 3)
            a = "三";
        int one = (int) (day % 10);
        switch (one) {
            case 1:
                a += "一";
                break;
            case 2:
                a += "二";
                break;
            case 3:
                a += "三";
                break;
            case 4:
                a += "四";
                break;
            case 5:
                a += "五";
                break;
            case 6:
                a += "六";
                break;
            case 7:
                a += "七";
                break;
            case 8:
                a += "八";
                break;
            case 9:
                a += "九";
                break;
        }
        return a;
    }
    
    /**
     * 阴历天表示转化为int值，如：廿三转化为23
     *
     * @return 解析失败返回0
     */
    public static int chinaDayToInt(String chinaDay) {
        if (chinaDay == null || chinaDay.length() == 0) {
            return 0;
        }
        
        if (chinaDay.length() > 2) {
            return 0;
        }
        
        if ("初十".equals(chinaDay)) {
            return 10;
        }
        
        if ("二十".equals(chinaDay)) {
            return 20;
        }
        
        if ("三十".equals(chinaDay)) {
            return 30;
        }
        
        String shiWei = chinaDay.length() == 2 ? chinaDay.substring(0, 1) : "";
        String geWei = chinaDay.length() == 2 ? chinaDay.substring(1) : chinaDay;
        
        int ten = 0;
        int bits = 0;
        if (shiWei.length() > 0) {
            switch (shiWei) {
                case "十":
                    ten = 10;
                    break;
                case "廿":
                    ten = 20;
                    break;
                case "三":
                    ten = 30;
                    break;
            }
        }
        
        switch (geWei) {
            case "一":
                bits = 1;
                break;
            case "二":
                bits = 2;
                break;
            case "三":
                bits = 3;
                break;
            case "四":
                bits = 4;
                break;
            case "五":
                bits = 5;
                break;
            case "六":
                bits = 6;
                break;
            case "七":
                bits = 7;
                break;
            case "八":
                bits = 8;
                break;
            case "九":
                bits = 9;
                break;
        }
        
        return ten + bits;
    }
    
    /**
     * 阴历月表示转化为int值，如：六月 转化为 6
     *
     * @return 解析失败返回0
     */
    public static int chinaMonthToInt(String month) {
        for (int i = 0; i < nStr1.length; i++) {
            if (nStr1[i].equals(month)) {
                return i;
            }
        }
        return 0;
    }
    
    /**
     * 获取农历表达的当天日期
     */
    @Nullable
    public static String today() {
        Calendar today = Calendar.getInstance(Locale.SIMPLIFIED_CHINESE);
        int year = today.get(Calendar.YEAR);
        int month = today.get(Calendar.MONTH) + 1;
        int date = today.get(Calendar.DATE);
        int[] l = solarToLunar(year, month, date);
        StringBuilder sToday = new StringBuilder();
        try {
            sToday.append(SDF.format(today.getTime()));
            sToday.append(" 农历");
            sToday.append(cyclical(year));
            sToday.append('(');
            sToday.append(getYearAnimal(year));
            sToday.append(")年");
            sToday.append(nStr1[l[1]]);
            sToday.append("月");
            sToday.append(getChinaDay(l[2]));
            return sToday.toString();
        } catch (Exception e) {
            return null;
        }
    }
    
    @Nullable
    public static String oneDay(int year, int month, int day) {
        int[] l = solarToLunar(year, month, day);
        StringBuilder sToday = new StringBuilder();
        try {
            sToday.append(" 农历");
            sToday.append(cyclical(year));
            sToday.append('(');
            sToday.append(getYearAnimal(year));
            sToday.append(")年");
            sToday.append(nStr1[l[1]]);
            sToday.append("月");
            sToday.append(getChinaDay(l[2]));
            return sToday.toString();
        } catch (Exception e) {
            return null;
        }
    }
    
    @SuppressLint("SimpleDateFormat")
    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy年M月d日 EEEEE");
    
    /**
     * 返回星座
     *
     * @return 星座
     */
    public static String getConstellation(int month, int day) {
        return day < dayArr[month - 1] ? constellationArr[month - 1] : constellationArr[month];
    }
    
    /**
     * 获取一年中的总月份
     */
    public static int getMonthByYear(int year) {
        if (getLeapMonth(year) == 0) {
            return 12;
        } else {
            return 13;
        }
    }
    
    
    /**
     * @param lunarYear 农历年份
     * @return String of Ganzhi: 甲子年
     * 甲乙丙丁戊己庚辛壬癸
     * 子丑寅卯辰巳无为申酉戌亥
     */
    public static String getLunarYearText(int lunarYear) {
        return Gan[(lunarYear - 4) % 10] + Zhi[(lunarYear - 4) % 12] + "年";
    }
    
    
    @SuppressLint("DefaultLocale")
    public static ArrayList<String> getYears(int startYear, int endYear) {
        ArrayList<String> years = new ArrayList<>();
        for (int i = startYear; i < endYear; i++) {
            years.add(String.format("%s(%d)", getLunarYearText(i), i));
        }
        return years;
    }
    
    /**
     * 获取year年的所有月份
     *
     * @param year 年
     * @return 月份列表
     */
    public static List<String> getMonths(int year) {
        ArrayList<String> baseMonths = new ArrayList<>();
        for (int i = 1; i < nStr1.length; i++) {
            baseMonths.add(nStr1[i] + "月");
        }
        if (getLeapMonth(year) != 0) {
            baseMonths.add(getLeapMonth(year), "闰" + nStr1[getLeapMonth(year)] + "月");
        }
        return baseMonths;
    }
    
    /**
     * 获取指定年的所有月份
     *
     * @param year             指定农历年
     * @param startMonth       农历开始月份
     * @param startMonthIsLeap 开始月份在指定年份是否是闰月
     * @param endMonth         农历结束月份
     * @param endMonthIsLeap   结束月份在指定年份是否是闰月
     * @return 月份列表
     */
    public static List<String> getMonths(int year, int startMonth, boolean startMonthIsLeap,
                                         int endMonth, boolean endMonthIsLeap) {
        ArrayList<String> baseMonths = new ArrayList<>();
        int leapMonth = getLeapMonth(year);
        for (int i = startMonth; i <= endMonth; i++) {
            if (i != startMonth || !startMonthIsLeap) {
                baseMonths.add(nStr1[i] + "月");
            }
            
            if (i == leapMonth && (i != endMonth || endMonthIsLeap)) {
                baseMonths.add("闰" + nStr1[leapMonth] + "月");
            }
        }
        
        return baseMonths;
    }
    
    
    /**
     * 获取每月农历显示名称
     *
     * @param maxDay 天
     * @return 名称列表
     */
    public static List<String> getLunarDays(int minDay, int maxDay) {
        ArrayList<String> days = new ArrayList<>();
        for (int i = minDay; i <= maxDay; i++) {
            days.add(getChinaDay(i));
        }
        return days;
    }
    
    /**
     * 农历转公历
     *
     * @param lunarYear  农历年
     * @param lunarMonth 农历月
     * @param lunarDay   农历天
     * @param isLeap     是否是闰年 0 false : 1 true
     * @return [0]新历年 [1]新历月 [2]新历日 [3]是否闰月 0 false : 1 true
     */
    public static int[] lunarToSolar(int lunarYear, int lunarMonth, int lunarDay, boolean isLeap) {
        int days = LUNAR_MONTH_DAYS[lunarYear - LUNAR_MONTH_DAYS[0]];
        int leap = getBitInt(days, 4, 13);
        int offset = 0;
        int loop = leap;
        if (!isLeap) {
            if (lunarMonth <= leap || leap == 0) {
                loop = lunarMonth - 1;
            } else {
                loop = lunarMonth;
            }
        }
        for (int i = 0; i < loop; i++) {
            offset += getBitInt(days, 1, 12 - i) == 1 ? 30 : 29;
        }
        offset += lunarDay;
        
        int solar11 = SOLAR_1_1[lunarYear - SOLAR_1_1[0]];
        
        int y = getBitInt(solar11, 12, 9);
        int m = getBitInt(solar11, 4, 5);
        int d = getBitInt(solar11, 5, 0);
        
        return solarFromInt(solarToInt(y, m, d) + offset - 1);
    }
    
    private static int[] solarFromInt(long g) {
        long y = (10000 * g + 14780) / 3652425;
        long ddd = g - (365 * y + y / 4 - y / 100 + y / 400);
        if (ddd < 0) {
            y--;
            ddd = g - (365 * y + y / 4 - y / 100 + y / 400);
        }
        long mi = (100 * ddd + 52) / 3060;
        long mm = (mi + 2) % 12 + 1;
        y = y + (mi + 2) / 12;
        long dd = ddd - (mi * 306 + 5) / 10 + 1;
        int[] solar = new int[4];
        solar[0] = (int) y;
        solar[1] = (int) mm;
        solar[2] = (int) dd;
        return solar;
    }
    
    /**
     * 公历转农历
     *
     * @param year  公历年
     * @param month 公历月
     * @param day   公历日
     * @return [0]农历年 [1]农历月 [2]农历日 [3]是否闰月 0 false : 1 true
     */
    public static int[] solarToLunar(int year, int month, int day) {
        int[] lunarInt = new int[4];
        int index = year - SOLAR_1_1[0];
        int data = (year << 9) | (month << 5) | (day);
        int solar11;
        if (SOLAR_1_1[index] > data) {
            index--;
        }
        solar11 = SOLAR_1_1[index];
        int y = getBitInt(solar11, 12, 9);
        int m = getBitInt(solar11, 4, 5);
        int d = getBitInt(solar11, 5, 0);
        long offset = solarToInt(year, month, day) - solarToInt(y, m, d);
        
        int days = LUNAR_MONTH_DAYS[index];
        int leap = getBitInt(days, 4, 13);
        
        int lunarY = index + SOLAR_1_1[0];
        int lunarM = 1;
        int lunarD;
        offset += 1;
        
        for (int i = 0; i < 13; i++) {
            int dm = getBitInt(days, 1, 12 - i) == 1 ? 30 : 29;
            if (offset > dm) {
                lunarM++;
                offset -= dm;
            } else {
                break;
            }
        }
        lunarD = (int) (offset);
        lunarInt[0] = lunarY;
        lunarInt[1] = lunarM;
        lunarInt[3] = 0;
        
        if (leap != 0 && lunarM > leap) {
            lunarInt[1] = lunarM - 1;
            if (lunarM == leap + 1) {
                lunarInt[3] = 1;
            }
        }
        lunarInt[2] = lunarD;
        return lunarInt;
    }
    
    private static int getBitInt(int data, int length, int shift) {
        return (data & (((1 << length) - 1) << shift)) >> shift;
    }
    
    private static long solarToInt(int y, int m, int d) {
        m = (m + 9) % 12;
        y = y - m / 10;
        return 365L * y + y / 4 - y / 100 + y / 400 + (m * 306 + 5) / 10
            + (d - 1);
    }
}